package eip.chapter5.sequence.impl;

import java.net.URISyntaxException;
import java.util.ArrayList;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.log4j.Logger;
import org.jibx.runtime.JiBXException;

import eip.chapter5.sequence.AbstractCheckoutBillService;
import eip.chapter5.sequence.Bill;
import eip.chapter5.sequence.BillIdentifierWrapper;
import eip.chapter5.sequence.CheckoutBill;
import eip.chapter5.sequence.util.BillingCalculator;
import eip.chapter5.sequence.util.JiBXHelper;

public class CheckoutBillServiceImpl extends AbstractCheckoutBillService implements MessageListener { 

	private static final Logger logger = Logger.getLogger(CheckoutBillServiceImpl.class);
	private int number;
	
	public CheckoutBillServiceImpl(int number) {
		setNumber(number);
		try {
			ActiveMQConnection connection = ActiveMQConnection.makeConnection("tcp://localhost:61616");
		    connection.start();
		    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		    Destination destination = session.createQueue("checkoutbill");
		    MessageConsumer consumer = session.createConsumer(destination);
		    consumer.setMessageListener(this);
		} catch(JMSException jms) {
			logger.error("error while connection to activemq", jms);
		} catch(URISyntaxException uri) {
			logger.error("error with activemq address", uri);
		}
	}
	
	public void onMessage(Message message) {
		TextMessage billMessage = (TextMessage) message;
		logger.info("received message " + billMessage);
		try {
			Bill bill = JiBXHelper.createBillFromXML(billMessage);
			logger.info("received bill " + bill + " number " + number 
					+ " size " + (billMap.size() + 1));
			String messageId = billMessage.getJMSMessageID();
			BillIdentifierWrapper billWrapper = new BillIdentifierWrapper(bill, messageId);
			processBill(billWrapper);
		} catch(JiBXException e) {
			logger.error("error while getting bill " + billMessage, e);
		} catch(JMSException e) {
			logger.error("error while getting bill " + billMessage, e);
		}
	}
	
	protected void sendCheckoutBill(String guestName) throws Exception {
		CheckoutBill checkoutBill = BillingCalculator.calculateBilling(
				billMap.get(guestName));
		ActiveMQConnection connection = ActiveMQConnection.makeConnection("tcp://localhost:61616");
	    connection.start();
	    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
	    Destination destination = session.createQueue("billing");
	    TextMessage billMessage = session.createTextMessage();
		billMessage.setJMSCorrelationID(getCorrelationID(billMap.get(guestName)));
		String strBill = JiBXHelper.createCheckoutBillinXML(checkoutBill);
		logger.info("sending checkoutbillMessage " + billMessage);
		billMessage.setText(strBill);
		MessageProducer producer = session.createProducer(destination);
		producer.send(billMessage);
		producer.close();
		connection.stop();
	}
	
	protected String getCorrelationID(ArrayList<BillIdentifierWrapper> billList) {
		if(billList == null || billList.size() == 0) return null;
		return billList.get(billList.size() - 1).getMessageId();
	}
	
	public void setNumber(int number) {
		this.number = number;
	}
	
}
